﻿using Microsoft.Office.Server.Search.Administration;
using Microsoft.SharePoint;
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.IO;
using System.Linq;
using System.Xml.Linq;

namespace SPSDeploy.Extensions.Extensions
{
    /// <summary>
    /// Search object owner extensions
    /// </summary>
    internal static class SearchObjectOwnerExtension
    {

        // Private members
        private static Guid empty = Guid.Empty;

        /// <summary>
        /// Return owner instance
        /// </summary>
        /// <param name="reader"></param>
        /// <returns></returns>
        internal static SearchObjectOwner GetOwner(SqlDataReader reader)
        {
            Guid farmId = reader["FarmId"] != DBNull.Value ? (Guid)reader["FarmId"] : empty;
            Guid siteId = reader["SiteCollectionId"] != DBNull.Value ? (Guid)reader["SiteCollectionId"] : empty;
            Guid webId = reader["SiteId"] != DBNull.Value ? (Guid)reader["SiteId"] : empty;
            try
            {
                if (farmId == empty && siteId == empty && webId == empty)
                    return new SearchObjectOwner(SearchObjectLevel.Ssa);
                else if (farmId != empty && siteId != empty && webId == empty)
                    return new SearchObjectOwner(SearchObjectLevel.SPSite, new SPSite(siteId).RootWeb);
                else if (farmId != empty && siteId != empty && webId != empty)
                    return new SearchObjectOwner(SearchObjectLevel.SPWeb, new SPSite(siteId).AllWebs[webId]);
            }
            catch (FileNotFoundException)
            {
            }
            return null;
        }

        /// <summary>
        /// Return schema owner instance
        /// </summary>
        /// <param name="reader"></param>
        /// <returns></returns>
        internal static SearchObjectOwner GetSchemaOwner(SqlDataReader reader)
        {
            if ((int)reader["SchemaId"] == 0 && reader["SiteCollectionId"] == DBNull.Value)
                return new SearchObjectOwner(SearchObjectLevel.Ssa);
            try
            {
                return new SearchObjectOwner(SearchObjectLevel.SPSite, new SPSite((Guid)reader["SiteCollectionId"]).RootWeb);
            }
            catch (FileNotFoundException)
            {
                return null;
            }
        }

        /// <summary>
        /// Return search object owner
        /// </summary>
        /// <param name="element"></param>
        /// <param name="owners"></param>
        /// <returns></returns>
        internal static SearchObjectOwner GetOwner(XElement element, List<SearchObjectOwner> owners)
        {
            SearchObjectOwner owner = owners.Where(i => i.Level.ToString() == element.Attribute("level").Value && i.SPSiteId.ToString() == element.Attribute("siteId").Value && (element.Attribute("webId") == null || i.SPWebId.ToString() == element.Attribute("webId").Value)).FirstOrDefault();
            if (owner == null)
                switch ((SearchObjectLevel)Enum.Parse(typeof(SearchObjectLevel), element.Attribute("level").Value))
                {
                    case SearchObjectLevel.Ssa:
                        owners.Add(owner = new SearchObjectOwner(SearchObjectLevel.Ssa));
                        break;
                    case SearchObjectLevel.SPSite:
                        owners.Add(owner = new SearchObjectOwner(SearchObjectLevel.SPSite, new SPSite(new Guid(element.Attribute("siteId").Value)).RootWeb));
                        break;
                    case SearchObjectLevel.SPWeb:
                        owners.Add(owner = new SearchObjectOwner(SearchObjectLevel.SPWeb, new SPSite(new Guid(element.Attribute("siteId").Value)).AllWebs[new Guid(element.Attribute("webId").Value)]));
                        break;
                }
            return owner;
        }

    }
}